package com.listeningframework.boot.commons.encrypt;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

/**
 * 
 * AES 对称加密算法
 *
 * @author lixining
 * @version $Id: AESEncodeUtils.java, v 0.1 2015年9月24日 下午5:34:06 lixining Exp $
 */
public class AESUtils {
    /**
     * AES对称加密算法-加密
     *
     * @param content 内容
     * @param key 加密KEY
     * @return String
     * @throws Exception 加密异常
     */
    public static String encode(String content, String key) throws Exception {
        return EncodeUtils.encodeBase64(encodeToBytes(content, key));
    }

    /**
     * uncheck aes encode
     *
     * @param content 加密内容
     * @param key 加密key
     * @return String
     */
    public static String safeEncode(String content, String key) {
        try {
            return EncodeUtils.encodeBase64(encodeToBytes(content, key));
        } catch (Exception e) {
            throw new RuntimeException("AES encode fail", e);
        }
    }

    /**
     * AES对称加密算法-解密
     *
     * @param content 解密内容
     * @param key 加解密KEY
     * @return String
     * @throws Exception 解密异常
     */
    public static String decode(String content, String key) throws Exception {
        return decodeByBytes(EncodeUtils.decodeBase64(content), key);
    }

    /**
     * Safe decode
     *
     * @param content 解密内容
     * @param key 解密KEY
     * @return String
     */
    public static String safeDecode(String content, String key) {
        try {
            return decodeByBytes(EncodeUtils.decodeBase64(content), key);
        } catch (Exception e) {
            throw new RuntimeException("AES decode fail", e);
        }
    }

    /**
     * AES对称加密算法加密
     *
     * @param content 待加密内容
     * @param key 加密KEY
     * @return String
     * @throws Exception 加密异常
     */
    private static byte[] encodeToBytes(String content, String key) throws Exception {
        KeyGenerator generator = KeyGenerator.getInstance("AES");
        generator.init(128, new SecureRandom(EncodeUtils.getBytes(key)));
        Cipher cipher = Cipher.getInstance("AES");
        byte[] keyBytes = generator.generateKey().getEncoded();
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"));
        return cipher.doFinal(EncodeUtils.getBytes(content));
    }

    /**
     * AES对称加密算法解密
     * 
     * @param encryptBytes 待解密字节数组
     * @param decryptKey 解密KEY
     * @return String
     * @throws Exception 解密异常
     */
    private static String decodeByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128, new SecureRandom(decryptKey.getBytes()));
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
        byte[] decryptBytes = cipher.doFinal(encryptBytes);
        return new String(decryptBytes);
    }
}
